/*
 *  Theory0039_Theory.cpp
 *  SoundController0002
 *
 *  Created by jiro on 11/07/17.
 *  Copyright 2011 jiro music. All rights reserved.
 *
 */

#include "Theory0039_TheoryTester.h"

#include "../Theory0039.h"
#include "../../../sc/Tester/CustomAssert.h"
#include "../../HarmonicSystem/HarmonicSound.h"
#include "../../HarmonicSystem/Sound.h"
#include "../../HarmonicSystem/HarmonicSystem.h"
#include <sstream>
#include <vector>
 
using namespace sc;
using namespace sc::hs;

namespace theory0039
{
	void TheoryTester::TestAll()
	{
		ClassifyChord000();
		ClassifyChord001();
		ClassifyChord002();
		ClassifyChord003();
		ClassifyChord004();
//		ClassifyChord005();	//output string for debug

		Test_Sort000();
		Test_Sort001();
		Test_Sort002();
	}

	void TheoryTester::ClassifyChord000()
	{
		std::vector< SingleGroupGenerator > generators;
		std::vector< sc::Note::Id > startNotes;
		ClassifiedChords classifiedChords;

		generators.push_back( 6 );
		generators.push_back( 3 );
		startNotes.push_back( sc::Note::A );
		startNotes.push_back( sc::Note::A );

		Theory::ClassifyChord( generators, startNotes, classifiedChords );

		std::vector< Chord > chords;
		chords = classifiedChords.GetChords( Theory::className_1_1 );
		AssertEqual( chords.size(), 9 );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::B ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::CSharp, sc::Note::B ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::F, sc::Note::B ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::DSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::CSharp, sc::Note::DSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::F, sc::Note::DSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::G ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::CSharp, sc::Note::G ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::F, sc::Note::G ) ) );

		chords = classifiedChords.GetChords( Theory::className_1_2 );
		AssertEqual( chords.size(), 9 );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::A ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::CSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::F ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::CSharp, sc::Note::A ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::CSharp, sc::Note::CSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::CSharp, sc::Note::F ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::F, sc::Note::A ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::F, sc::Note::CSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::F, sc::Note::F ) ) );

		chords = classifiedChords.GetChords( Theory::className_2_1_1 );
		AssertEqual( chords.size(), 0 );
		chords = classifiedChords.GetChords( Theory::className_2_1_2 );
		AssertEqual( chords.size(), 0 );
		chords = classifiedChords.GetChords( Theory::className_2_2 );
		AssertEqual( chords.size(), 0 );
	}

	void TheoryTester::ClassifyChord001()
	{
		std::vector< SingleGroupGenerator > generators;
		std::vector< sc::Note::Id > startNotes;
		ClassifiedChords classifiedChords;

		generators.push_back( 6 );
		generators.push_back( 3 );
		startNotes.push_back( sc::Note::A );
		startNotes.push_back( sc::Note::B );

		Theory::ClassifyChord( generators, startNotes, classifiedChords );

		std::vector< Chord > chords;
		chords = classifiedChords.GetChords( Theory::className_1_1 );
		AssertEqual( chords.size(), 9 );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::B ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::DSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::G ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::B ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::DSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::G ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::B ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::DSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::G ) ) );

		chords = classifiedChords.GetChords( Theory::className_1_2 );
		AssertEqual( chords.size(), 9 );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::B, sc::Note::B ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::DSharp, sc::Note::B ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::G, sc::Note::B ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::B, sc::Note::DSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::DSharp, sc::Note::DSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::G, sc::Note::DSharp ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::B, sc::Note::G ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::DSharp, sc::Note::G ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::G, sc::Note::G ) ) );

		chords = classifiedChords.GetChords( Theory::className_2_1_1 );
		AssertEqual( chords.size(), 0 );
		chords = classifiedChords.GetChords( Theory::className_2_1_2 );
		AssertEqual( chords.size(), 0 );
		chords = classifiedChords.GetChords( Theory::className_2_2 );
		AssertEqual( chords.size(), 0 );

	}

	void TheoryTester::ClassifyChord002()
	{
		std::vector< SingleGroupGenerator > generators;
		std::vector< sc::Note::Id > startNotes;
		ClassifiedChords classifiedChords;

		generators.push_back( 6 );
		generators.push_back( 3 );
		startNotes.push_back( sc::Note::A );
		startNotes.push_back( sc::Note::BFlat );

		Theory::ClassifyChord( generators, startNotes, classifiedChords );

		std::vector< Chord > chords;
		chords = classifiedChords.GetChords( Theory::className_1_1 );
		AssertEqual( chords.size(), 0 );
		chords = classifiedChords.GetChords( Theory::className_1_2 );
		AssertEqual( chords.size(), 0 );
		chords = classifiedChords.GetChords( Theory::className_2_1_1 );
		AssertEqual( chords.size(), 0 );
		chords = classifiedChords.GetChords( Theory::className_2_1_2 );
		AssertEqual( chords.size(), 0 );

		chords = classifiedChords.GetChords( Theory::className_2_2 );
		AssertEqual( chords.size(), 18 );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::BFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::D ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::GFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::BFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::D ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::GFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::BFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::D ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::GFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::B, sc::Note::BFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::DSharp, sc::Note::BFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::G, sc::Note::BFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::B, sc::Note::D ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::DSharp, sc::Note::D ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::G, sc::Note::D ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::B, sc::Note::GFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::DSharp, sc::Note::GFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::G, sc::Note::GFlat ) ) );
	}
	
	void TheoryTester::ClassifyChord003()
	{
		std::vector< SingleGroupGenerator > generators;
		std::vector< sc::Note::Id > startNotes;
		ClassifiedChords classifiedChords;

		generators.push_back( 2 );
		generators.push_back( 6 );
		generators.push_back( 3 );
		startNotes.push_back( sc::Note::A );
		startNotes.push_back( sc::Note::A );
		startNotes.push_back( sc::Note::A );

		Theory::ClassifyChord( generators, startNotes, classifiedChords );

		std::vector< Chord > chords;
		chords = classifiedChords.GetChords( Theory::className_1_1 );
		AssertEqual( chords.size(), 24 );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::B, sc::Note::A  ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::B, sc::Note::DFlat  ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::B, sc::Note::F ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::EFlat, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::EFlat, sc::Note::F ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::G, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::G, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::G, sc::Note::F ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::A, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::A, sc::Note::F ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::B, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::B, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::B, sc::Note::F ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::DFlat, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::DFlat, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::DFlat, sc::Note::F ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::EFlat, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::EFlat, sc::Note::F ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::F, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::F, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::F, sc::Note::F ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::G, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::G, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::G, sc::Note::F ) ) );

		chords = classifiedChords.GetChords( Theory::className_1_2 );
		AssertEqual( chords.size(), 12 );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::A, sc::Note::DFlat  ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::A, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::A, sc::Note::F  ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::DFlat, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::DFlat, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::DFlat, sc::Note::F ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::EFlat, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::F, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::F, sc::Note::DFlat ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::F, sc::Note::F ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::A, sc::Note::A ) ) ); 
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::EFlat, sc::Note::A ) ) ); 

 		chords = classifiedChords.GetChords( Theory::className_2_1_1 );
		AssertEqual( chords.size(), 0 );
		chords = classifiedChords.GetChords( Theory::className_2_1_2 );
		AssertEqual( chords.size(), 0 );

		chords = classifiedChords.GetChords( Theory::className_2_2 );
		AssertEqual( chords.size(), 0 );

	}

	void TheoryTester::ClassifyChord004()
	{
		std::vector< SingleGroupGenerator > generators;
		std::vector< sc::Note::Id > startNotes;
		ClassifiedChords classifiedChords;

		generators.push_back( 2 );
		generators.push_back( 6 );
		generators.push_back( 3 );
		startNotes.push_back( sc::Note::A );
		startNotes.push_back( sc::Note::BFlat );
		startNotes.push_back( sc::Note::AFlat );

		Theory::ClassifyChord( generators, startNotes, classifiedChords );

		std::vector< Chord > chords;
		chords = classifiedChords.GetChords( Theory::className_1_1 );
		AssertEqual( chords.size(), 0 );

		chords = classifiedChords.GetChords( Theory::className_1_2 );
		AssertEqual( chords.size(), 0 );

 		chords = classifiedChords.GetChords( Theory::className_2_1_1 );
		AssertEqual( chords.size(), 12 );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::BFlat, sc::Note::AFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::BFlat, sc::Note::C ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::D, sc::Note::C ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::D, sc::Note::E ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::FSharp, sc::Note::AFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::FSharp, sc::Note::E ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::BFlat, sc::Note::AFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::BFlat, sc::Note::C ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::D, sc::Note::C ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::GFlat, sc::Note::AFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::GFlat, sc::Note::E ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::D, sc::Note::E ) ) );

		chords = classifiedChords.GetChords( Theory::className_2_1_2 );
		AssertEqual( chords.size(), 18 );

		chords = classifiedChords.GetChords( Theory::className_2_2 );
		AssertEqual( chords.size(), 6 );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::C, sc::Note::C ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::E, sc::Note::E ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::A, sc::Note::GSharp, sc::Note::AFlat ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::C, sc::Note::C ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::E, sc::Note::E ) ) );
		AssertTrue( Theory::IsContain( chords, Chord( sc::Note::EFlat, sc::Note::GSharp, sc::Note::E ) ) );
	}

	void TheoryTester::ClassifyChord005()
	{
		std::vector< SingleGroupGenerator > generators;
		std::vector< sc::Note::Id > startNotes;
		ClassifiedChords classifiedChords;

		generators.push_back( 4 );
		generators.push_back( 6 );
		generators.push_back( 3 );
		startNotes.push_back( sc::Note::B );
		startNotes.push_back( sc::Note::E );
		startNotes.push_back( sc::Note::EFlat );

		Theory::ClassifyChord( generators, startNotes, classifiedChords );

		std::vector< Chord > chords11;
		chords11 = classifiedChords.GetChords( Theory::className_1_1 );
		AssertEqual( chords11.size(), 8 );

		std::vector< Chord > chords1_2;
		chords1_2 = classifiedChords.GetChords( Theory::className_1_2 );
		AssertEqual( chords1_2.size(), 0 );

		std::vector< Chord > chords_211;
		chords_211 = classifiedChords.GetChords( Theory::className_2_1_1 );
		AssertEqual( chords_211.size(), 8 );

		std::vector< Chord > chords_21_2;
		chords_21_2 = classifiedChords.GetChords( Theory::className_2_1_2 );
		AssertEqual( chords_21_2.size(), 48 );

		std::vector< Chord > chords_2_2;
		chords_2_2 = classifiedChords.GetChords( Theory::className_2_2 );
		AssertEqual( chords_2_2.size(), 8 );
		
		
		std::vector< std::vector< Chord >* > chordsList;
		chordsList.push_back( & chords11 );
		chordsList.push_back( & chords1_2 );
		chordsList.push_back( & chords_211 );
		chordsList.push_back( & chords_21_2 );
		chordsList.push_back( & chords_2_2 );
		for ( int j = 0; j < chordsList.size(); j++ )
		{
			std::cout << "class " << classifiedChords.GetClassNameOfIndex( j ) << ":\n";
			for ( int i = 0; i < chordsList[ j ]->size(); i++ )
			{
				const Chord& chord = chordsList[ j ]->at( i );
				std::cout << "\t" << chord.ToString() << "\t";
				for ( int intervalIndex = 1; intervalIndex < chord.GetIntervalCount(); intervalIndex++ )
				{
					sc::Note::Id id0;
					sc::Note::Id id1;
					chord.GetNoteIdsOfIntervalIndex( intervalIndex, id0, id1 );
					
					std::cout << "" << "(" << sc::Note::ToString( id0 );
//					int spaceCount = 2 - sc::Note::ToString( id0 ).size();
//					for ( int k = 0; k < spaceCount; k++ )
//					{
//						std::cout << " ";
//					}
					std::cout << ", " << sc::Note::ToString( id1 );

//					spaceCount = 2 - sc::Note::ToString( id1 ).size();
//					for ( int k = 0; k < spaceCount; k++ )
//					{
//						std::cout << " ";
//					}
					std::cout << ") = "
//							  << sc::Note::IntervalToString( chord.GetIntervalOfIndex( intervalIndex ), true ) << "\t";
							  << chord.GetIntervalOfIndex( intervalIndex ) << "\t";
				}
				int generatorCount = chord.GetGeneratorCount();
				std::set< std::string > degreeTexts;
				for ( int k = 0; k < generatorCount; k++ )
				{
					const SingleGroupGenerator& generator = chord.GetGeneratorOfIndex( k );
//					std::cout << "α^" << 12 / generator.GetDegree() << ": " 
//							  << sc::Note::ToString( chord.GetGeneratorStartNoteIdOfIndex( k ) ) << "\t";
					std::stringstream ss;
					ss << "α^" << 12 / generator.GetDegree() << ": " 
							  << sc::Note::ToString( chord.GetGeneratorStartNoteIdOfIndex( k ) ) << "\t";
					degreeTexts.insert( ss.str() );
				}
				for ( std::set< std::string >::iterator iter = degreeTexts.begin(); iter != degreeTexts.end(); iter++ )
				{
					std::cout << *iter;
				}
				std::cout << std::endl;
			}
		}
	}

	void TheoryTester::Test_Sort000()
	{
		std::vector< sc::hs::Sound::NearbyWellTemperamentNotes > sortedNotesList;
		Sound::NearbyWellTemperamentNotes notes;
		notes.insert( sc::hs::Sound::NearbyWellTemperamentNotePair( HarmonicSound( Sound::SingleSineWave, Note::C4, 1 ), Note::C4 ) );
		notes.insert( sc::hs::Sound::NearbyWellTemperamentNotePair( HarmonicSound( Sound::SingleSineWave, Note::CSharp4, 1 ), Note::CSharp4 ) );
	
		Theory::Sort( notes, sortedNotesList );
		AssertEqual( sortedNotesList.size(), 12 );
		for ( int i = 0; i < 12; i++ )
		{
			if ( i == Note::C or i == Note::CSharp )
			{
				continue;
			}
//			cout << i << endl;
			AssertEqual( sortedNotesList[ i ].size(), 0 ); 
		}
		AssertEqual( sortedNotesList[ Note::C ].size(), 1 );
		AssertEqual( sortedNotesList[ Note::C ].begin()->second, Note::C4 );

		AssertEqual( sortedNotesList[ Note::CSharp ].size(), 1 );
		AssertEqual( sortedNotesList[ Note::CSharp ].begin()->second, Note::CSharp4 );
	}

	void TheoryTester::Test_Sort001()
	{
		sc::hs::Chord chord;
		chord.push_back( Sound( Sound::SingleSineWave, sc::Note::C4, 0 ) );
		const sc::hs::Sound::NearbyWellTemperamentNotes& notes = chord.GetNearbyWellTemperamentNotes();
//		cout << Sound::ToString( notes, -1 ) << endl << endl;

		std::vector< sc::hs::Sound::NearbyWellTemperamentNotes > sortedNotesList;
		Theory::Sort( notes, sortedNotesList );
//		for ( int i = 0; i < 12; i++ )
//		{
//			cout << Sound::ToString( sortedNotesList[ i ], -1 ) << endl;
//		}
		AssertEqual( sortedNotesList[ Note::ASharp ].size(), 1 );
		AssertEqual( sortedNotesList[ Note::B ].size(), 1 );
		AssertEqual( sortedNotesList[ Note::CSharp ].size(), 2 );
		AssertEqual( sortedNotesList[ Note::D ].size(), 2 );
		AssertEqual( sortedNotesList[ Note::DSharp ].size(), 2 );
		AssertEqual( sortedNotesList[ Note::E ].size(), 1 );
		AssertEqual( sortedNotesList[ Note::G ].size(), 5 );

/*
note: B_3(246.942Hz) is near by C4(261.626)'s 1th(261.626Hz), ∂=14.6839Hz
note: C#_4(277.183Hz) is near by C4(261.626)'s 1th(261.626Hz), ∂=15.5571Hz
note: G_5(783.991Hz) is near by C4(261.626)'s 3th(784.877Hz), ∂=0.885824Hz
note: E_6(1318.51Hz) is near by C4(261.626)'s 5th(1308.13Hz), ∂=10.3824Hz
note: G_6(1567.98Hz) is near by C4(261.626)'s 6th(1569.75Hz), ∂=1.77165Hz
note: D_7(2349.32Hz) is near by C4(261.626)'s 9th(2354.63Hz), ∂=5.31194Hz
note: G_7(3135.96Hz) is near by C4(261.626)'s 12th(3139.51Hz), ∂=3.5433Hz
note: C#_8(4434.92Hz) is near by C4(261.626)'s 17th(4447.63Hz), ∂=12.7125Hz
note: D_8(4698.64Hz) is near by C4(261.626)'s 18th(4709.26Hz), ∂=10.6239Hz
note: D#_8(4978.03Hz) is near by C4(261.626)'s 19th(4970.89Hz), ∂=7.146Hz
note: G_8(6271.93Hz) is near by C4(261.626)'s 24th(6279.01Hz), ∂=7.08659Hz
note: D#_9(9956.06Hz) is near by C4(261.626)'s 38th(9941.77Hz), ∂=14.292Hz
note: G_9(12543.9Hz) is near by C4(261.626)'s 48th(12558Hz), ∂=14.1732Hz
note: A#_9(14917.2Hz) is near by C4(261.626)'s 57th(14912.7Hz), ∂=4.58315Hz
*/
	}

	void TheoryTester::Test_Sort002()
	{
		sc::hs::Chord chord;
		chord.push_back( Sound( Sound::SingleSineWave, sc::Note::C4, 0 ) );
		chord.push_back( Sound( Sound::SingleSineWave, sc::Note::CSharp3, 0 ) );
		const sc::hs::Sound::NearbyWellTemperamentNotes& notes = chord.GetNearbyWellTemperamentNotes();
//		cout << Sound::ToString( notes, -1, false, true ) << endl << endl;

		std::vector< sc::hs::Sound::NearbyWellTemperamentNotes > sortedNotesList;
		Theory::Sort( notes, sortedNotesList );
//		for ( int i = 0; i < sortedNotesList.size(); i++ )
//		{
//			cout << sortedNotesList[ i ].size() << endl;
//			cout << Sound::ToString( sortedNotesList[ i ], 1024, true, true ) << endl;
//		}
		AssertEqual( sortedNotesList[ Note::ASharp ].size(), 2 );
		AssertEqual( sortedNotesList[ Note::B ].size(), 4 );
		AssertEqual( sortedNotesList[ Note::C ].size(), 10 );
		AssertEqual( sortedNotesList[ Note::CSharp ].size(), 10 );
		AssertEqual( sortedNotesList[ Note::D ].size(), 5 );
		AssertEqual( sortedNotesList[ Note::DSharp ].size(), 5 );
		AssertEqual( sortedNotesList[ Note::E ].size(), 4 );
		AssertEqual( sortedNotesList[ Note::F ].size(), 2 );
		AssertEqual( sortedNotesList[ Note::G ].size(), 5 );
		AssertEqual( sortedNotesList[ Note::GSharp ].size(), 6 );

/*
note: B_2(123.471Hz) is near by C#_3(138.591)'s 1th(138.591Hz), ∂=15.1205Hz
note: C_3(130.813Hz) is near by C#_3(138.591)'s 1th(138.591Hz), ∂=7.77853Hz
note: D_3(146.832Hz) is near by C#_3(138.591)'s 1th(138.591Hz), ∂=8.24107Hz
note: C4(261.626Hz) is near by C#_3(138.591)'s 2th(277.183Hz), ∂=15.5571Hz
note: G#_4(415.305Hz) is near by C#_3(138.591)'s 3th(415.774Hz), ∂=0.469249Hz
note: F_5(698.456Hz) is near by C#_3(138.591)'s 5th(692.957Hz), ∂=5.49989Hz
note: G#_5(830.609Hz) is near by C#_3(138.591)'s 6th(831.548Hz), ∂=0.938498Hz
note: D#_6(1244.51Hz) is near by C#_3(138.591)'s 9th(1247.32Hz), ∂=2.8139Hz
note: F_6(1396.91Hz) is near by C#_3(138.591)'s 10th(1385.91Hz), ∂=10.9998Hz
note: G#_6(1661.22Hz) is near by C#_3(138.591)'s 12th(1663.1Hz), ∂=1.877Hz
note: C_7(2093Hz) is near by C#_3(138.591)'s 15th(2078.87Hz), ∂=14.1348Hz
note: D_7(2349.32Hz) is near by C#_3(138.591)'s 17th(2356.05Hz), ∂=6.73422Hz
note: D#_7(2489.02Hz) is near by C#_3(138.591)'s 18th(2494.64Hz), ∂=5.62781Hz
note: E_7(2637.02Hz) is near by C#_3(138.591)'s 19th(2633.23Hz), ∂=3.78546Hz
note: G#_7(3322.44Hz) is near by C#_3(138.591)'s 24th(3326.19Hz), ∂=3.75399Hz
note: A#_7(3729.31Hz) is near by C#_3(138.591)'s 27th(3741.97Hz), ∂=12.6554Hz
note: D_8(4698.64Hz) is near by C#_3(138.591)'s 34th(4712.1Hz), ∂=13.4684Hz
note: D#_8(4978.03Hz) is near by C#_3(138.591)'s 36th(4989.29Hz), ∂=11.2556Hz
note: E_8(5274.04Hz) is near by C#_3(138.591)'s 38th(5266.47Hz), ∂=7.57092Hz
note: G#_8(6644.88Hz) is near by C#_3(138.591)'s 48th(6652.38Hz), ∂=7.50798Hz
note: B_8(7902.13Hz) is near by C#_3(138.591)'s 57th(7899.7Hz), ∂=2.42784Hz
note: E_9(10548.1Hz) is near by C#_3(138.591)'s 76th(10532.9Hz), ∂=15.1418Hz
note: G#_9(13289.8Hz) is near by C#_3(138.591)'s 96th(13304.8Hz), ∂=15.016Hz
note: B_9(15804.3Hz) is near by C#_3(138.591)'s 114th(15799.4Hz), ∂=4.85567Hz
note: B_3(246.942Hz) is near by C4(261.626)'s 1th(261.626Hz), ∂=14.6839Hz
note: C#_4(277.183Hz) is near by C4(261.626)'s 1th(261.626Hz), ∂=15.5571Hz
note: G_5(783.991Hz) is near by C4(261.626)'s 3th(784.877Hz), ∂=0.885824Hz
note: E_6(1318.51Hz) is near by C4(261.626)'s 5th(1308.13Hz), ∂=10.3824Hz
note: G_6(1567.98Hz) is near by C4(261.626)'s 6th(1569.75Hz), ∂=1.77165Hz
note: D_7(2349.32Hz) is near by C4(261.626)'s 9th(2354.63Hz), ∂=5.31194Hz
note: G_7(3135.96Hz) is near by C4(261.626)'s 12th(3139.51Hz), ∂=3.5433Hz
note: C#_8(4434.92Hz) is near by C4(261.626)'s 17th(4447.63Hz), ∂=12.7125Hz
note: D_8(4698.64Hz) is near by C4(261.626)'s 18th(4709.26Hz), ∂=10.6239Hz
note: D#_8(4978.03Hz) is near by C4(261.626)'s 19th(4970.89Hz), ∂=7.146Hz
note: G_8(6271.93Hz) is near by C4(261.626)'s 24th(6279.01Hz), ∂=7.08659Hz
note: D#_9(9956.06Hz) is near by C4(261.626)'s 38th(9941.77Hz), ∂=14.292Hz
note: G_9(12543.9Hz) is near by C4(261.626)'s 48th(12558Hz), ∂=14.1732Hz
note: A#_9(14917.2Hz) is near by C4(261.626)'s 57th(14912.7Hz), ∂=4.58315Hz
*/
	}


}
